<?php
class visit_counter {
    /**
     *main Object
     */
    static $ci;

    static $now;
    static $offset;
    static $sunday;

    function visit_counter() {
        self::$ci =& get_instance();
        self::$ci->load->database();
        self::$now = time();
        self::$offset = 0;
        self::$sunday = 0;
    }
    
    public static function view($visit_type = 'guests') {
        self::_insertRecord(time(), $visit_type);
    }    

    public static function getVisitCounter() {
        $visits = array();
        $datetime = self::getTimeStart();
        $now = time();
        //get visit in day
        $visits['thisDay'] = self::getVisits($datetime['local_todaystart'], $now);
        
        $visits['thisWeed'] = self::getVisits($datetime['local_xweekstart'], $now);

        $visits['thisMonth'] = self::getVisits($datetime['local_xmonthstart'], $now);

        $visits['lastMonth'] = self::getVisits($datetime['local_lmonthstart'], $datetime['local_xmonthstart'] - 1);

        return $visits;
    }
 
    function getAllVisit() {
        $query = 'SELECT sum(visits) as visits from visit_counter';
        $ret = self::$ci->db->query($query);
        $ret = $ret->row_array();
        return $ret['visits'];
    }

    function getVisits($timestart=0, $timestop=0){

        $timestart  = (int) $timestart;
        $timestop   = (int) $timestop;

        $total      = array('visits'=>0, 'guests'=>0, 'bots'=>0, 'members'=>0);

        $query      =   " SELECT * FROM visit_counter WHERE '1=1'";
        $query      .=  ($timestart) ? " AND time > $timestart " : "";
        $query      .=  ($timestop) ? " AND time <= $timestop " : "";

        // Get a database object
        $ret = self::$ci->db->query($query);

        $records = $ret->result();

        if ( !empty($records) && count($records) ) {
            foreach ( $records as $record ) {
                $total['visits']    +=  (int) $record->visits;
                $total['guests']    +=  (int) $record->guests;
                $total['bots']      +=  (int) $record->bots;
                $total['members']   +=  (int) $record->members;
            }
        }

        return $total;
    }

    /*
     * Insert New Record
     */
    private function _insertRecord($time=0, $visit_type='guests'){
        $time   =   (int) $time;

        $query  =   " INSERT INTO visit_counter (time, visits, $visit_type)" .
                    " VALUES ($time, 1, 1) ON DUPLICATE KEY UPDATE visits=visits+1, $visit_type=$visit_type+1;";

        return self::$ci->db->query($query);
    }

    /*
     * Update Record
     */
    private function _updateRecord($time=0, $visit_type='guests'){
        $time   =   (int) $time;

        $query  =   " UPDATE visit_counter" .
                    " SET visits=visits+1, $visit_type=$visit_type+1 WHERE time=$time;";

        return self::$ci->db->query($query);
    }


    public function getTimeStart(){
        $now = time();

        /* ------------------------------------------------------------------------------------------------ */
        // Determine GMT Time (UTC+00:00)
        // Determine this minute, this hour, this day, this month, this year
        // Don't use strftime()
        $minute         = (int) gmstrftime( "%M", $now );
        $hour           = (int) gmstrftime( "%H", $now );
        $day            = (int) gmstrftime( "%d", $now );
        $month          = (int) gmstrftime( "%m", $now );
        $year           = (int) gmstrftime( "%Y", $now );

        // Determine Starting GMT Time and Local Time of Today
        $todaystart         = gmmktime( 0,0,0,$month,$day,$year );
        $local_todaystart   = self::localTimeStart( $todaystart, "day");

        // Determine Starting GMT Time and Local Time of Yesterday
        $yesterdaystart         = $todaystart - 86400;
        $local_yesterdaystart   = $local_todaystart - 86400;

        // Determine Starting GMT Time and Local Time of This Week
        // If Sunday is starting day of week then Sunday = 0 ... Saturday = 6
        // If Monday is starting day of week then Monday = 0 ... Sunday = 6
        $weekday            = (int) gmstrftime("%w", $now );
        $wk = $weekday - self::$sunday;
        $weekday = ($wk > 0) ? $wk : 7+$wk;

        $xweekstart         =   $todaystart - $weekday*86400;
        $local_xweekstart   =   self::localTimeStart( $xweekstart, "week");

        // Determine Starting GMT Time and Local Time of Last Week
        $lweekstart         =   $xweekstart - 7*86400;
        $local_lweekstart   =   $local_xweekstart - 7*86400;

        // Determine Starting GMT Time and Local Time of This Month
        $xmonthstart        =   gmmktime( 0,0,0,$month,1,$year );
        $local_xmonthstart  =   self::localTimeStart( $xmonthstart, "month");

        // Determine Starting GMT Time and Local Time of Last Month
        // $days_lmonth: Number days of the last month (28/29, 30 or 31)
        $days_lmonth        =   (int) gmstrftime("%d", $xmonthstart - 86400 );
        $lmonthstart        =   $xmonthstart - $days_lmonth*86400;
        $local_lmonthstart  =   $local_xmonthstart - $days_lmonth*86400;
        
        $datetime   =   array();

        $datetime["todaystart"]             =   $todaystart;
        $datetime["local_todaystart"]       =   $local_todaystart;
        $datetime["yesterdaystart"]         =   $yesterdaystart;
        $datetime["local_yesterdaystart"]   =   $local_yesterdaystart;
        $datetime["xweekstart"]             =   $xweekstart;
        $datetime["local_xweekstart"]       =   $local_xweekstart;
        $datetime["lweekstart"]             =   $lweekstart;
        $datetime["local_lweekstart"]       =   $local_lweekstart;
        $datetime["xmonthstart"]            =   $xmonthstart;
        $datetime["local_xmonthstart"]      =   $local_xmonthstart;
        $datetime["lmonthstart"]            =   $lmonthstart;
        $datetime["local_lmonthstart"]      =   $local_lmonthstart;

        return $datetime;
    }

    /*
     * Determine Local Starting Time
     * Return Unix Time
     * Example: If Global Time (GMT+00:00) = 1182124800 (2007/06/18 - 00:00:00)
     *          then Local Time (GMT+07:00) = 1182124800 - 7*3600 = 1182099600,
     *          Local Time (GMT-05:00) = 1182124800 + 5*3600 = 1182142800
     */
    public function localTimeStart($timestart, $type="day"){
        $now    = self::$now;
        $offset = self::$offset;

        $timestart = (int) $timestart;

        $type = strtolower(trim($type));
        $type = (($type == "week") || ($type == "month")) ? $type : "day";
        $nexttimestart = strtotime("+1 $type", $timestart);
        $lasttimestart = strtotime("-1 $type", $timestart);

        if ($offset > 0){
            $timestart = ($now > ($nexttimestart - $offset*3600)) ? $nexttimestart : $timestart;
        }
        elseif($offset < 0){
            $timestart = ($now < ($timestart - $offset*3600)) ? $lasttimestart : $timestart;
        }
        $timestart -= $offset*3600;
        
        return $timestart;
    }
}
?>